#ifndef _NO_ACE_COMPONENT
#include "ace/config.h"
#include "ace_Proactor.h"
namespace XGC
{
	namespace net
	{
		CProactor::CProactor(void)
		: lock_ ()
		, sem_ ((unsigned int) 0)
		, proactor_(0) 
		{

		}

		CProactor::~CProactor()
		{
			(void) this->stop ();
			(void) this->delete_proactor();
		}

		int CProactor::create_proactor ( size_t max_op )
		{
			ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX,
				monitor,
				this->lock_,
				-1);

			ACE_ASSERT (this->proactor_ == 0);

		#if defined (ACE_WIN32)

			ACE_UNUSED_ARG (max_op);

			ACE_WIN32_Proactor *proactor_impl = 0;

			ACE_NEW_RETURN (proactor_impl,
				ACE_WIN32_Proactor,
				-1);

			ACE_DEBUG ((LM_DEBUG,
				ACE_TEXT("(%t) Create Proactor Type = WIN32\n")));

		#elif defined (ACE_HAS_AIO_CALLS)

			ACE_POSIX_Proactor * proactor_impl = 0;

			switch (type_proactor)
			{
			case AIOCB:
				ACE_NEW_RETURN (proactor_impl,
					ACE_POSIX_AIOCB_Proactor (max_op),
					-1);
				ACE_DEBUG ((LM_DEBUG,
					ACE_TEXT ("(%t) Create Proactor Type = AIOCB\n")));
				break;

		#if defined(ACE_HAS_POSIX_REALTIME_SIGNALS)
			case SIG:
				ACE_NEW_RETURN (proactor_impl,
					ACE_POSIX_SIG_Proactor (max_op),
					-1);
				ACE_DEBUG ((LM_DEBUG,
					ACE_TEXT ("(%t) Create Proactor Type = SIG\n")));
				break;
		#endif /* ACE_HAS_POSIX_REALTIME_SIGNALS */

		#  if defined (sun)
			case SUN:
				ACE_NEW_RETURN (proactor_impl,
					ACE_SUN_Proactor (max_op),
					-1);
				ACE_DEBUG ((LM_DEBUG,
					ACE_TEXT("(%t) Create Proactor Type = SUN\n")));
				break;
		#  endif /* sun */

		#  if !defined(ACE_HAS_BROKEN_SIGEVENT_STRUCT)
			case CB:
				ACE_NEW_RETURN (proactor_impl,
					ACE_POSIX_CB_Proactor (max_op),
					-1);
				ACE_DEBUG ((LM_DEBUG,
					ACE_TEXT ("(%t) Create Proactor Type = CB\n")));
				break;
		#  endif /* !ACE_HAS_BROKEN_SIGEVENT_STRUCT */

			default:
				ACE_DEBUG ((LM_DEBUG,
					ACE_TEXT ("(%t) Create Proactor Type = DEFAULT\n")));
				break;
			}

		#endif /* ACE_WIN32 */

			// always delete implementation  1 , not  !(proactor_impl == 0)
			ACE_NEW_RETURN (this->proactor_,
				ACE_Proactor (proactor_impl, 1 ),
				-1);
			// Set new singleton and delete it in close_singleton()
			ACE_Proactor::instance (this->proactor_, 1);
			return 0;
		}

		int
		CProactor::delete_proactor (void)
		{
			ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX,
				monitor,
				this->lock_,
				-1);

			ACE_DEBUG ((LM_DEBUG,
				ACE_TEXT ("(%t) Delete Proactor\n")));

			ACE_Proactor::close_singleton ();
			this->proactor_ = 0;

			return 0;
		}

		int
		CProactor::start (int num_threads, size_t max_op)
		{
			if (this->create_proactor ( max_op ) == -1)
				ACE_ERROR_RETURN ((LM_ERROR,
				ACE_TEXT ("%p.\n"),
				ACE_TEXT ("unable to create proactor")),
				-1);

			if (this->activate (THR_NEW_LWP, num_threads) == -1)
				ACE_ERROR_RETURN ((LM_ERROR,
				ACE_TEXT ("%p.\n"),
				ACE_TEXT ("unable to activate thread pool")),
				-1);

			for (; num_threads > 0; num_threads--)
			{
				sem_.acquire ();
			}

			return 0;
		}

		int
		CProactor::stop ()
		{
			if (this->proactor_ != 0)
			{
				ACE_DEBUG ((LM_DEBUG,
					ACE_TEXT ("(%t) Calling End Proactor event loop\n")));

				this->proactor_->proactor_end_event_loop ();
			}

			if (this->wait () == -1)
				ACE_ERROR ((LM_ERROR,
				ACE_TEXT ("%p.\n"),
				ACE_TEXT ("unable to stop thread pool")));

			return 0;
		}

		int
		CProactor::svc (void)
		{
			ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Task started\n")));

			// disable_signal (ACE_SIGRTMIN, ACE_SIGRTMAX);

			// signal that we are ready
			sem_.release (1);

			ACE_Proactor::run_event_loop ();

			ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Task finished\n")));
			return 0;
		}
	}
}
#endif
